home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / libs / pnm / pnm.c < prev    next >
C/C++ Source or Header  |  1997-02-02  |  5KB  |  207 lines

  1. /*
  2. *******************************************************************************
  3. ** Codecs for PNM                                                            **
  4. ** (c) Klaus Gebhardt, 1997                                                  **
  5. *******************************************************************************
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10.  
  11. #include "oct-img.h"
  12.  
  13. extern UINT PutByte (FILE *, UCHAR);
  14. extern UINT GetByte (FILE *, UCHAR *);
  15.  
  16. extern UINT GetBShort (FILE *, SHORT *);
  17.  
  18. extern UINT ScanUCHAR (FILE *, UCHAR *);
  19. extern UINT ScanUINT  (FILE *, UINT *);
  20.  
  21. extern UCHAR **malloc_uchar_matrix (UINT, UINT);
  22. extern INT   **malloc_int_matrix   (UINT, UINT);
  23.  
  24. extern UCHAR **compute_colormap (INT **, UINT, UINT, INT *);
  25.  
  26.  
  27. static UINT PNM_writepixels (FILE *fp, UINT x, UINT y, INT **pixels,
  28.                  INT colors, UCHAR **cm, INT n)
  29. {
  30.   UINT i, j, nbyte = 0;
  31.   INT k;
  32.  
  33.   for (j = 0; j < y; j++)
  34.     for (i = 0; i < x; i++)
  35.       for (k = 0; k < n; k++)
  36.     nbyte += PutByte (fp, cm[k][pixels[j][i]]);
  37.  
  38.   return nbyte;
  39. }
  40.  
  41.  
  42. BOOL PNM_Encode (FILE *fp, INT grey, UINT x, UINT y, INT **pixels,
  43.          INT colors, UCHAR **cm)
  44. {
  45.   UINT nbyte = 0;
  46.  
  47.   if ((x == 0) || (y == 0) || (colors == 0)) return -1;
  48.  
  49.   if (grey != OCT_RGB)
  50.     {
  51.       fprintf (fp, "P5\n%i %i\n255\n", x, y);
  52.       nbyte += PNM_writepixels (fp, x, y, pixels, colors, cm, 1);
  53.       nbyte += PutByte (fp, '\n');
  54.  
  55.       if (nbyte != (x * y + 1))  return -1;
  56.       return 0;
  57.     }
  58.   else
  59.     {
  60.       fprintf (fp, "P6\n%i %i\n255\n", x, y);
  61.       nbyte += PNM_writepixels (fp, x, y, pixels, colors, cm, 3);
  62.       nbyte += PutByte (fp, '\n');
  63.  
  64.       if (nbyte != (3 * x * y + 1))  return -1;
  65.       return 0;
  66.     }
  67. }
  68.  
  69.  
  70. static BOOL PNM_readinit (FILE *fp, UINT *y, UINT *x, UINT *m, SHORT *fmt)
  71. {
  72.   if (GetBShort (fp, fmt) != 2)  return -1;
  73.  
  74.   switch (*fmt)
  75.     {
  76.     case PPM_TYPE:
  77.     case RPPM_TYPE:
  78.       if (ScanUINT (fp, x) == 0)  return -1;
  79.       if (ScanUINT (fp, y) == 0)  return -1;
  80.       if (ScanUINT (fp, m) == 0)  return -1;
  81.       if ((*m) > PPM_MAXVAL)      return -1;
  82.       return 0;
  83.  
  84.     case PGM_TYPE:
  85.     case RPGM_TYPE:
  86.       if (ScanUINT (fp, x) == 0)  return -1;
  87.       if (ScanUINT (fp, y) == 0)  return -1;
  88.       if (ScanUINT (fp, m) == 0)  return -1;
  89.       if ((*m) > PGM_MAXVAL)      return -1;
  90.       return 0;
  91.  
  92.     case PBM_TYPE:
  93.     case RPBM_TYPE:
  94.       if (ScanUINT (fp, x) == 0)  return -1;
  95.       if (ScanUINT (fp, y) == 0)  return -1;
  96.       *m = PBM_MAXVAL;
  97.       return 0;
  98.  
  99.     default:
  100.       return -1;
  101.     }
  102. }
  103.  
  104.  
  105. static BOOL PNM_readrow (FILE *fp, INT *row, UINT cx, UINT maxval, SHORT fmt)
  106. {
  107.   UINT x;
  108.   UCHAR r, g, b;
  109.   int bitshift = -1;
  110.  
  111.   switch (fmt)
  112.     {
  113.     case PPM_TYPE:
  114.       for (x = 0; x < cx; x++)
  115.     {
  116.       if (ScanUCHAR (fp, &r) == 0)  return -1;
  117.       if (ScanUCHAR (fp, &g) == 0)  return -1;
  118.       if (ScanUCHAR (fp, &b) == 0)  return -1;
  119.       row[x] = (((INT) r) << 16) | (((INT) g) << 8) | ((INT) b);
  120.     }
  121.       return 0;
  122.  
  123.     case RPPM_TYPE:
  124.       for (x = 0; x < cx; x++)
  125.     {
  126.       if (GetByte (fp, &r) != 1)  return -1;
  127.       if (GetByte (fp, &g) != 1)  return -1;
  128.       if (GetByte (fp, &b) != 1)  return -1;
  129.       row[x] = (((INT) r) << 16) | (((INT) g) << 8) | ((INT) b);
  130.     }
  131.       return 0;
  132.  
  133.     case PGM_TYPE:
  134.       for (x = 0; x < cx; x++)
  135.     {
  136.       if (ScanUCHAR (fp, &g) == 0)  return -1;
  137.       row[x] = (((INT) g) << 16) | (((INT) g) << 8) | ((INT) g);
  138.     }
  139.       return 0;
  140.  
  141.     case RPGM_TYPE:
  142.       for (x = 0; x < cx; x++)
  143.     {
  144.       if (GetByte (fp, &g) != 1)  return -1;
  145.       row[x] = (((INT) g) << 16) | (((INT) g) << 8) | ((INT) g);
  146.     }
  147.       return 0;
  148.  
  149.     case PBM_TYPE:
  150.       for (x = 0; x < cx; x++)
  151.     {
  152.       if (ScanUCHAR (fp, &g) == 0)  return -1;
  153.       g = (g == 0) ? 255 : 0;
  154.       row[x] = (((INT) g) << 16) | (((INT) g) << 8) | ((INT) g);
  155.     }
  156.       return 0;
  157.  
  158.     case RPBM_TYPE:
  159.       for (x = 0; x < cx; x++)
  160.     {
  161.       if ( bitshift == -1 )
  162.         {
  163.           if (GetByte (fp, &g) != 1)  return -1;
  164.           bitshift = 7;
  165.         }
  166.       b = (((g >> bitshift) & 1) == 0) ? 255 : 0;
  167.       row[x] = (((INT) b) << 16) | (((INT) b) << 8) | ((INT) b);
  168.       --bitshift;
  169.     }
  170.       return 0;
  171.  
  172.     default:
  173.       return -1;
  174.     }
  175. }
  176.  
  177.  
  178. BOOL PNM_Decode (FILE *fp, UINT *x, UINT *y, INT *col_min, INT *col_max,
  179.          UCHAR ***cm, INT ***pixels)
  180. {
  181.   UINT r, m;
  182.   SHORT fmt;
  183.  
  184.   *cm = NULL;
  185.   *col_min = 0;
  186.   *col_max = 0;
  187.  
  188.   PNM_readinit (fp, y, x, &m, &fmt );
  189.  
  190.   if ((*pixels = malloc_int_matrix (*y, *x)) == NULL)  return -1;
  191.  
  192.   for (r = 0; r < *y; r++)
  193.     if (PNM_readrow (fp, (*pixels)[r], *x, m, fmt) == -1)
  194.       {
  195.     free (*pixels);
  196.     return -1;
  197.       }
  198.  
  199.   if ((*cm = compute_colormap (*pixels, *y, *x, col_max)) == NULL)
  200.     {
  201.       free (*pixels);
  202.       return -1;
  203.     }
  204.  
  205.   return 0;
  206. }
  207.